package com.goicter.commons.utils.http;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

/**
 * cookes操作公共类
 * 
 */
public class CookieUtils {

	public static final String VALUE_ENCODE = "UTF-8";

	public static final String DEFAULT_PATH = "/";

	/**
	 * 默认一年
	 */
	public static final int DEFAULT_MAX_AGE = 60 * 60 * 24 * 365;

	/**
	 * 新增cookie
	 * 
	 * @param response
	 * @param key
	 *            名称
	 * @param value
	 *            值
	 * @param domain
	 *            域名范围
	 * @param path
	 *            路径范围
	 * @param maxAge
	 *            失效时间(如果为null:Session级，如果为0删除cookie)
	 */
	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final String domain,
			final String path, final Integer maxAge) {
		String encodedValue;
		try {
			encodedValue = value == null ? "" : URLEncoder.encode(value,
					VALUE_ENCODE);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		Cookie c = new Cookie(key, encodedValue);
		if (domain != null) {
			c.setDomain(domain);
		}
		c.setPath(path);
		if (maxAge != null) {
			c.setMaxAge(maxAge);
		}
		response.addCookie(c);
	}

	/**
	 * 
	 * @param response
	 * @param key
	 * @param value
	 * @param path
	 * @param maxAge
	 */
	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final String path,
			final Integer maxAge) {
		addCookie(response, key, value, null, path, maxAge);
	}

	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final Integer maxAge) {
		addCookie(response, key, value, null, DEFAULT_PATH, maxAge);
	}

	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value) {
		addCookie(response, key, value, null, DEFAULT_PATH, DEFAULT_MAX_AGE);
	}

	public static final void removeCookie(final HttpServletResponse response,
			final String key, final String domain, final String path) {
		addCookie(response, key, "", domain, path, 0);
	}

	public static final void removeCookie(final HttpServletResponse response,
			final String key, final String path) {
		addCookie(response, key, "", null, path, 0);
	}

	public static final void removeCookie(final HttpServletResponse response,
			final String key) {
		addCookie(response, key, "", null, DEFAULT_PATH, 0);
	}

	public static final String getCookie(final HttpServletRequest request,
			final String key) {
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return null;
		}
		for (Cookie c : cookies) {
			if (StringUtils.equals(key, c.getName())) {
				try {
					return URLDecoder.decode(c.getValue(), VALUE_ENCODE);
				} catch (UnsupportedEncodingException e) {
					throw new RuntimeException(e);
				}
			}
		}
		return null;
	}

	/**
	 * 得到cookies值
	 * 
	 * @param request
	 * @param cookieName
	 * @param key
	 * @return
	 */
	public static String[] getCookieValue(final HttpServletRequest request,
			final String cookieName) {
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return null;
		}
		for (int i = 0; i < cookies.length; i++) {
			Cookie cookie = cookies[i];
			if (cookie.getName().equals(cookieName)) {
				String cookieValueTemp = null;
				try {
					cookieValueTemp = URLDecoder.decode(cookie.getValue(),
							VALUE_ENCODE);
				} catch (UnsupportedEncodingException e) {
				}
				if (StringUtils.isEmpty(cookieValueTemp)) {
					return null;
				}
				String[] cookieValuesArray = cookieValueTemp.split("\\^~");
				return cookieValuesArray;
			}
		}
		return null;
	}

	/**
	 * 得到cookies值
	 * 
	 * @param request
	 * @param cookieName
	 * @param key
	 * @return
	 */
	public static String getCookieValue(final HttpServletRequest request,
			final String cookieName, final String key) {
		String[] cookieValuesArray = getCookieValue(request, cookieName);
		return getCookieValue(cookieValuesArray, key);
	}

	/**
	 * 得到cookies值
	 * 
	 * @param request
	 * @param cookieValues
	 * @param key
	 * @return
	 */
	public static String getCookieValue(final String[] cookieValues,
			final String key) {
		if (cookieValues == null || cookieValues.length < 1) {
			return null;
		}
		for (int j = 0; j < cookieValues.length; ++j) {
			String cookieValue = cookieValues[j];
			String[] temp = cookieValue.split("=");
			if ((temp.length >= 2) && (key.equals(temp[0]))) {
				return temp[1];
			}
		}
		return null;
	}

	public static Map<String, String> getCookieValueMap(
			final String[] cookieValues) {
		if (cookieValues == null || cookieValues.length < 1) {
			return null;
		}
		Map<String, String> map = new HashMap<String, String>();
		for (int j = 0; j < cookieValues.length; ++j) {
			String cookieValue = cookieValues[j];
			String[] temp = cookieValue.split("=");
			if (temp.length > 0) {
				map.put(temp[0], temp.length == 2 ? temp[1] : null);
			}
		}
		return map;
	}

	/**
	 * 获得cookie
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @param name
	 *            cookie name
	 * @return if exist return cookie, else return null.
	 */
	public static Cookie getOrigCookie(HttpServletRequest request, String name) {
		Cookie[] cookies = request.getCookies();
		if (cookies != null && cookies.length > 0) {
			for (Cookie c : cookies) {
				if (c.getName().equals(name)) {
					return c;
				}
			}
		}
		return null;
	}

	/**
	 * 
	 * @param response
	 * @param key
	 * @param value
	 * @param domain
	 * @param path
	 * @param maxAge
	 *            an integer specifying the maximum age of the cookie in
	 *            seconds; if negative, means the cookie is not stored; if zero,
	 *            deletes the cookie
	 */
	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final String domain,
			final String path, final int maxAge) {
		String encodedValue;
		try {
			encodedValue = value == null ? "" : URLEncoder.encode(value,
					VALUE_ENCODE);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		Cookie c = new Cookie(key, encodedValue);
		if (domain != null) {
			c.setDomain(domain);
		}
		c.setPath(path);
		c.setMaxAge(maxAge);
		response.addCookie(c);
	}

	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final String path,
			final int maxAge) {
		addCookie(response, key, value, null, path, maxAge);
	}

	public static final void addCookie(final HttpServletResponse response,
			final String key, final String value, final int maxAge) {
		addCookie(response, key, value, null, DEFAULT_PATH, maxAge);
	}

	public static final void addMCookie(final HttpServletResponse response,
			final String key, final String value) {
		addCookie(response, key, value, null, DEFAULT_PATH, DEFAULT_MAX_AGE);
	}

	public static final void removeMCookie(final HttpServletResponse response,
			final String key, final String domain, final String path) {
		addCookie(response, key, "", domain, path, 0);
	}

	public static final void removeMCookie(final HttpServletResponse response,
			final String key, final String path) {
		addCookie(response, key, "", null, path, 0);
	}

	public static final void removeMCookie(final HttpServletResponse response,
			final String key) {
		addCookie(response, key, "", null, DEFAULT_PATH, 0);
	}

	public static final String getMCookie(HttpServletRequest request, String key) {
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return null;
		}
		for (Cookie c : cookies) {
			if (StringUtils.equals(key, c.getName())) {
				try {
					return URLDecoder.decode(c.getValue(), VALUE_ENCODE);
				} catch (UnsupportedEncodingException e) {
					throw new RuntimeException(e);
				}
			}
		}
		return null;
	}
}
